/**
 * Title: DownloadHttpResponseHandler.java
 * Description:
 * Copyright: Copyright (c) 2008
 * Company:深圳彩讯科技有限公司
 * Author 罗旭东 (hi@luoxudong.com)
 * Date 2013-8-9 下午5:19:31
 * Version 1.0 
 */
package com.luoxudong.phonenumber.service.net.http.asynchttp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.SocketException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpStatus;

import com.luoxudong.phonenumber.service.exception.PhoneNumberException;
import com.luoxudong.phonenumber.service.exception.PhoneNumberExceptionCode;
import com.luoxudong.phonenumber.service.net.http.filetransfer.interfaces.IDownloadListener;
import com.luoxudong.phonenumber.service.net.http.filetransfer.manager.DownloadManager;
import com.luoxudong.phonenumber.service.net.http.httpclient.HttpEntity;
import com.luoxudong.phonenumber.service.net.http.httpclient.HttpHeaders;
import com.luoxudong.phonenumber.service.net.http.httpclient.HttpResponse;
import com.luoxudong.phonenumber.service.utils.EvtLog;

/** 
 * ClassName: DownloadHttpResponseHandler 
 * Description:下载请求结果回调
 * Create by 罗旭东
 * Date 2013-8-9 下午5:19:31 
 */
public class DownloadHttpResponseHandler extends BinaryHttpResponseHandler{
	private static final String TAG = "DownloadHttpResponseHandler";
	/**
	 * 下载监听
	 */
	private List<IDownloadListener> downloadListeners = null;
	private String filePath = null;
	
	private String fileName = null;
	
	private int errorCode;
	
	public DownloadHttpResponseHandler(int downloadId, List<IDownloadListener> downloadListeners)
	{
		super(downloadId);
		this.downloadListeners = downloadListeners;
	}
	
	@Override
	protected void sendResponseMessage(HttpResponse response) {
		byte[] buffer = new byte[10 * 1024];
		int length = 0;
		long totalLength = 0;//更新下载文件总长度
		HttpEntity httpEntity = response.getEntity();
		if (httpEntity.isChunked())//Chunked解码
		{
			if (fileSize >= 0)//中间件有传入文件大小
			{
				totalLength = fileSize;
			}
			else {
				totalLength = httpEntity.getContentLength();
			}
			
		}
		else
		{
			totalLength = httpEntity.getContentLength();
		}
		
		if (totalLength < 0)
		{
			sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), new PhoneNumberException("下载文件长度无效"));
			return;
		}
		
		
		RandomAccessFile randomAccessFile = null;
		
		File localFile = new File(filePath, fileName);
		
		if (!localFile.getParentFile().exists())//父文件夹不存在则创建
		{
			localFile.getParentFile().mkdirs();
		}
		
		try {
			boolean isNewFile = !localFile.exists();
			randomAccessFile = new RandomAccessFile(localFile, "rwd");
			if (isNewFile)//新文件
			{
				randomAccessFile.setLength(totalLength);
			}
		} catch (FileNotFoundException e1) {
			sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), new PhoneNumberException("文件不存在!"));
			return;
		} catch (IOException e) {
			if (randomAccessFile != null)
			{
				try {
					randomAccessFile.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), new PhoneNumberException("IO异常!"));
			return;
		}
		
		
		long compmeted = 0;

		if (response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT)
		{
			EvtLog.w(TAG, "不支持断点下载!");
			compmeted = 0;
		}
		
		InputStream instream = null;
		try {
			instream = httpEntity.getContent();
			
			EvtLog.d(TAG, "从" + compmeted + "位置开始下载");
			randomAccessFile.seek(compmeted);
			
			while (compmeted != totalLength && length != -1) {
				length = instream.read(buffer);
				
				if (length == -1)
				{
					break;
				}
				
				compmeted += length;
				randomAccessFile.write(buffer, 0, length);
				EvtLog.d(TAG, "下载进度:" + compmeted + "/" + totalLength);
				if (downloadListeners != null)
				{
					for (IDownloadListener listener : downloadListeners)
					{
						listener.onDownloading(transferId, compmeted, totalLength);
					}
				}
			}
			
			if (compmeted == totalLength)// 下载完成
			{
				onTransferSuccess();
			}
			else if (compmeted > totalLength)
			{
				sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), new PhoneNumberException("本地文件长度超过总长度!"));
				return;
			}
			
		} catch (IllegalStateException e) {
			sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), e);
			e.printStackTrace();
		} catch (SocketException e) {
			sendFailureMessage(PhoneNumberExceptionCode.httpSocketException.getErrorCode(), e);
		}
		catch (IOException e) {
			sendFailureMessage(PhoneNumberExceptionCode.defaultExceptionCode.getErrorCode(), e);
			e.printStackTrace();
		}finally
		{
			if (randomAccessFile != null)
			{
				try {
					randomAccessFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if (instream != null)
			{
				try {
					instream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@Override
	public void addHttpHeader(Map<String, String> headerFields) {
		//增加断点下载信息
		long length = 0;
		File file = new File(filePath, fileName);
		
		if (file.exists())
		{
			length = file.length();
		}
		
		if (headerFields == null)
		{
			headerFields = new HashMap<String, String>();
		}
		
		if (length != 0)
		{
			headerFields.put(HttpHeaders.RANGE, "bytes=" + length + "-");
		}
	}
	
	@Override
	public void onFailure(int errorCode, String errorMsg, Throwable e) {
		EvtLog.e(TAG, "下载失败!!!!!");
		for (IDownloadListener listener : downloadListeners)
		{
			listener.onDownloadFail(transferId, errorCode, errorMsg);
		}
		
		onTransferFinish();
	}
	
	@Override
	protected void onTransferSuccess() {
		EvtLog.e(TAG, "下载完成!!!!!");
		if (downloadListeners != null)
		{
			for (IDownloadListener listener : downloadListeners)
			{
				listener.onDownloadSuccess(transferId);
			}
		}
		
		onTransferFinish();
	}
	
	@Override
	protected void onTransferFinish() {
		DownloadManager.removeDownloadTask(transferId);
	}
	
	@Override
	protected void onTransferPause() {
		// 传输暂停
		EvtLog.e(TAG, "停止下载!!!!!");
		onTransferFinish();
	}
	
	@Override
	protected void onTransferStart() {
		synchronized (downloadListeners) {
			if (downloadListeners != null)
			{
				for (IDownloadListener downloadListener : downloadListeners)
				{
					downloadListener.onStartDownload(transferId);
				}
			}
		}
	}

	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
}
